#!/usr/bin/env bash

# ----------------------------------------------------------------------
# Filename:   ft-lib.sh
# Version:    1.0
# Date:       2020/04/22
# Author:     Lz
# Email:      lz843723683@163.com
# History：     
#             Version 1.0, 2020/04/22
# Function:   定义用于版本特性系统测试常用变量和函数
# ----------------------------------------------------------------------
readonly TPASS=0
readonly TFAIL=1
readonly TCONF=2

## TODO: 用户界面
#    In: $1 => 字符串文字
USAGE_FTLIB(){
#	cat >&1 <<EOF
#   \033[1m\033[;32m$1\033[0m

#EOF
	printf "#  \033[1m\033[;35m %s \033[0m\n\n" "$1"
}


## TODO : 测试前的初始化 
#     In: $1 => 清除函数名
#    Out: 
#         0=> TPASS
#         1=> TFAIL
#         other=> TCONF
Init_FTLIB(){
	# 判断是否传入清除函数
	if [ $# -ne 1 ];then
		echo "Fail : Must specify \"clean function!\""
		exit ${TCONF}
	else
		# 定义清除函数
		fileClean_ftlib="$1"
	fi

	# 判断root用户
	if [ `id -u` -ne 0 ];then
		echo "Must use root ！"
		exit ${TCONF}
	fi

	# 信号捕获ctrl+c
	trap 'OnCtrlC_FTLIB' INT
	
	# 结果判断
	fsRet_ftlib=${TPASS}
}


## TODO: 解析函数返回值,当不为"False"时则退出(为空也退出)
#  In  : $1 => log
#        $2 => 是否退出测试，False为不退出
RetParse_FTLIB(){
	# 必须第一位
	local ret=$?

	local logstr=""
	local flag=""

	if [ $# -eq 1 ];then
		logstr="$1"
	elif [ $# -eq 2 ];then
		logstr="$1"
		flag="$2"
	fi

	if [ $ret -eq 0 ];then
		# 成功
		printf "[\033[32m Pass \033[0m]: %s\n\n" "${logstr}"
		return ${TPASS}
	else
		# 失败
		fsRet_ftlib=${TFAIL}		
	
		printf "[\033[;31m Fail \033[0m]: %s\n\n" "${logstr}"
		if [ "Z${flag}" == "ZFalse"  ];then
			# 继续执行
			return ${TFAIL}
		else
			# 退出
			Exit_FTLIB
		fi
	fi
}


## TODO: ctrl+c之后自动步骤
#   Out: 
#       Success => TPASS 
#       Failed  => TFAIL
#       Conf    => TCONF
OnCtrlC_FTLIB(){
	echo "正在优雅的退出..."

	# ctrl+c退出
	Exit_FTLIB
}


## TODO: 调用程序退出函数
#    In: $1 => 调用脚本结果值
Exit_FTLIB(){
	# 调用清除函数
	Clean_FTLIB

	if [ $# -eq "1" -a "$1" != "${TPASS}" ];then
		exit ${1}
	fi
	
	if [ ${fsRet_ftlib} != ${TPASS} ];then
		exit ${fsRet_ftlib}
	fi

	exit ${TPASS}
}


## TODO: 清除操作
#
Clean_FTLIB(){
	# 判断是否指定清除操作
	if [ "Z${fileClean_ftlib}" == "Z" ];then
		echo "TCONF: 未指定清除函数"
	else
		# 执行清除函数
		eval ${fileClean_ftlib}		
	fi
}

#######################################################
## TODO: 返回结果
#   In :
#	$1 => ${TPASS} / ${TFAIL} / ${TCONF}
#   Out:
#	$TPASS
#	$TFAIL
#	$TCONF
OutputRet_FTLIB(){
	local flag=$1

	if [ $flag -eq ${TPASS} ];then
		return ${TPASS}
	elif [ $flag -eq ${TFAIL} ];then
		return ${TFAIL}
	else
		return ${TCONF}
	fi
}


## TODO: 判断软件包是否集成
#   In :
#	$1 => isExist / noExist
#	$2 => yes / no. 是否需要静默输出
#       $3 => yes / no. 是否需要集成LTF自带的过滤规则
#	$4 => Package Name,支持正则表达式
#   Out:
#	$TPASS => 如果$1为isExist，存在指定软件包。若$1为noExist，不存在指定软件包
#	$TFAIL => 如果$1为isExist，不存在指定软件包。若$1为noExist，存在指定软件包
#	$TCONF => 代码问题
PkgExist_FTLIB(){
	if [ $# -ne 4  ];then
		echo "[ Error ]: Function PkgExist_FTLIB"
		return $TCONF
	fi
	
	local flag="$1"
	local quiet="$2"
	local rule="$3"
	local pkgname="$4"
	local ret=0

	# 判断软件包是否存在
	if [ Z"$quiet" == Z"yes" ];then
		if [ "Z${rule}" == "Zno" ];then
		# 不需要添加规则
			rpm -qa | grep -q "${pkgname}"
		else
		# 添加规则
			rpm -qa | grep -q "^${pkgname}-[0-9]"
		fi
	else
		echo "rpm -qa | grep ${pkgname} :"
		if [ "Z${rule}" == "Zno" ];then
		# 不需要添加规则
			rpm -qa | grep "${pkgname}"
		else
		# 添加规则
			rpm -qa | grep "^${pkgname}-[0-9]"
		fi
	fi
	ret=$?

	# 如果不存在软件包
	if [ $ret -ne 0 ];then
		echo "未安装软件包 ${pkgname} "
	fi

	if [ Z"$flag" == Z"noExist"  ];then
		if [ $ret -eq 0 ];then
		# 存在软件包
			return $TFAIL
		else
		# 不存在软件包
			return $TPASS
		fi	
	else
		if [ $ret -eq 0 ];then
		# 存在软件包
			return $TPASS
		else
		# 不存在软件包
			return $TFAIL
		fi
	fi	

	return $ret
}


## TODO: 判断 多个软件包是否集成
#   In :
#	$1 => isExist / noExist
#	$2 => yes / no. 是否需要静默输出
#       $3 => yes / no. 是否需要集成LTF自带的过滤规则
#	$4 => Package Name,支持正则表达式
#   Out:
#	$TPASS => 如果$1为isExist，存在指定软件包。若$1为noExist，不存在指定软件包
#	$TFAIL => 如果$1为isExist，不存在指定软件包。若$1为noExist，存在指定软件包
#	$TCONF => 代码问题
PkgExistArr_FTLIB(){
	if [ $# -ne 4  ];then
		echo "[ Error ]: Function PkgExistArr_FTLIB"
		return $TCONF
	fi
	
	local flag="$1"
	local quiet="$2"
	local rule="$3"
	local pkgname=""
	local pkgnamearr="$4"
	local ret="$TPASS"

	local tmpret="$TPASS"
	local existpkg=""
	local noexistpkg=""

	# 遍历所有软件包
	for pkgname in ${pkgnamearr[@]}
	do
		# 判断软件包务是否已经存在
		PkgExist_FTLIB "$flag" "$quiet" "$rule" "$pkgname"
		tmpret=$?

		if [ "$flag" == "isExist" -a $tmpret -eq $TPASS ];then
		# 已经安装软件包
			existpkg="$existpkg $pkgname"
		elif [ "$flag" == "isExist" -a $tmpret -eq $TFAIL ];then
		# 未安装的软件包
			noexistpkg="$noexistpkg $pkgname"
			ret=$TFAIL
		elif [ "$flag" == "noExist" -a $tmpret -eq $TPASS ];then
		# 未安装的软件包
			noexistpkg="$noexistpkg $pkgname"
		elif [ "$flag" == "noExist" -a $tmpret -eq $TFAIL ];then
		# 已经安装软件包
			existpkg="$existpkg $pkgname"
			ret=$TFAIL
		else
		# 异常
			echo "[ Error ]: PkgExistArr_FTLIB function Results Abnormal (flag=$flag , ret=$tmpret)"
			return $TCONF
		fi
	done

	# 判断是否静默输出	
	if [ Z"$quiet" == Z"no" ];then
		echo ""
		echo "已安装的软件包: ($existpkg )"
		echo "未安装的软件包: ($noexistpkg )"
	fi

	return $ret
}


## TODO: 判断服务是否存在
#   In :
#	$1 => isExist / noExist
#	$2 => yes / no. 是否需要静默输出
#	$3 => Service Name
#   Out:
#	$TPASS => 如果$1为isExist，存在指定服务。若$1为noExist，不存在指定服务
#	$TFAIL => 如果$1为isExist，不存在指定服务。若$1为noExist，存在指定服务
#	$TCONF => 代码问题
SvcExist_FTLIB(){
	if [ $# -ne 3  ];then
		echo "[ Error ]: Function SvcExist_FTLIB"
		return $TCONF
	fi
	
	local flag="$1"
	local quiet="$2"
	local svcname="$3"
	local ret=0
	
	# 判断是否存在systemctl
	which systemctl &>/dev/null
	if [ $? -eq 0 ];then
	# 存在systemctl
		# 判断服务是否存在,如果存在则返回0
		if [ Z"$quiet" == Z"yes" ];then
			systemctl is-enabled $svcname 2>&1 | grep -q -v "No such file or directory"
			ret=$?
		else
			echo -n "systemctl is-enabled $svcname : "
			systemctl is-enabled $svcname
	
			systemctl is-enabled $svcname 2>&1 | grep -q -v "No such file or directory"
			ret=$?
		fi
	else
		# 判断是否需要静默输出
		if [ Z"$quiet" == Z"yes" ];then
			chkconfig --list | grep -q "$svcname"
			ret=$?
		else
			echo "chkconfig --list | grep $svcname"
			chkconfig --list | grep  $svcname
			ret=$?
		fi
	fi


	# 如指定noExist则结果反转
	if [ Z"$flag" == Z"noExist"  ];then
		if [ $ret -eq 0 ];then
		# 服务存在
			return $TFAIL
		else
		# 服务不存在
			return $TPASS
		fi
	else
		if [ $ret -eq 0 ];then
		# 服务存在
			return $TPASS
		else
		# 服务不存在
			return $TFAIL
		fi
	fi	

	return $ret
}


## TODO: 判断 多个服务是否存在
#   In :
#	$1 => isExist / noExist
#	$2 => yes / no. 是否需要静默输出
#	$3 => Service Name
#   Out:
#	$TPASS => 如果$1为isExist，存在指定服务。若$1为noExist，不存在指定服务
#	$TFAIL => 如果$1为isExist，不存在指定服务。若$1为noExist，存在指定服务
#	$TCONF => 代码问题
SvcExistArr_FTLIB(){
	if [ $# -ne 3  ];then
		echo "[ Error ]: Function SvcActiveArr_FTLIB"
		return $TCONF
	fi
	
	local flag="$1"
	local quiet="$2"
	local svcname=""
	local svcnamearr="$3"
	local ret="$TPASS"

	local tmpret="$TPASS"
	local existsvc=""
	local noexistsvc=""

	# 遍历所有服务
	for svcname in ${svcnamearr[@]}
	do
		# 判断服务是否存在
		SvcExist_FTLIB "$flag" "$quiet" "$svcname"
		tmpret=$?

		if [ "$flag" == "isExist" -a $tmpret -eq $TPASS ];then
		# 服务当前存在
			existsvc="$existsvc $svcname"
		elif [ "$flag" == "isExist" -a $tmpret -eq $TFAIL ];then
		# 服务当前不存在
			noexistsvc="$noexistsvc $svcname"
			ret=$TFAIL
		elif [ "$flag" == "noExist" -a $tmpret -eq $TPASS ];then
		# 服务当前不存在
			noexistsvc="$noexistsvc $svcname"
		elif [ "$flag" == "noExist" -a $tmpret -eq $TFAIL ];then
		# 服务当前存在
			existsvc="$existsvc $svcname"
			ret=$TFAIL
		else
		# 异常
			echo "[ Error ]: SvcExistArr_FTLIB function Results Abnormal (flag=$flag , ret=$tmpret)"
			return $TCONF
		fi
	done

	# 判断是否静默输出	
	if [ Z"$quiet" == Z"no" ];then
		echo "存在以下服务: ($existsvc )"
		echo "不存在以下服务: ($noexistsvc )"
	fi

	return $ret
}


## TODO: 判断服务是否已经激活
#   In :
#	$1 => isActive / noActive
#	$2 => yes / no. 是否需要静默输出
#	$3 => Service Name
#   Out:
#	$TPASS => 如果$1为isActive，指定服务已启动。若$1为noActive，指定服务未启动
#	$TFAIL => 如果$1为isActive，指定服务未启动。若$1为noActive，指定服务已启动
#	$TCONF => 代码问题
SvcActive_FTLIB(){
	if [ $# -ne 3  ];then
		echo "[ Error ]: Function SvcActive_FTLIB"
		return $TCONF
	fi
	
	local flag="$1"
	local quiet="$2"
	local svcname="$3"
	local ret=0

        # 判断是否存在systemctl
        which systemctl &>/dev/null
        if [ $? -eq 0 ];then
		# 判断服务当前是否已经激活,如果激活则返回0.(若服务不存在算作未激活)
		if [ Z"$quiet" == Z"yes" ];then
			systemctl is-active $svcname > /dev/null
			ret=$?
		else
			echo -n "systemctl is-active $svcname : "
			systemctl is-active $svcname
			ret=$?
		fi
	else
		if [ Z"$quiet" == Z"yes" ];then
			service $svcname status &>/dev/null
			ret=$?
		else
			echo -n "service $svcname status :"
			service $svcname status
			ret=$?
		fi

	fi

	# 如指定noActive则结果反转
	if [ Z"$flag" == Z"noActive"  ];then
		if [ $ret -eq 0 ];then
		# 服务已启动
			return $TFAIL
		else
		# 服务未启动
			return $TPASS
		fi	
	else
		if [ $ret -eq 0 ];then
		# 服务已启动
			return $TPASS
		else
		# 服务未启动
			return $TFAIL
		fi
	fi	

	return $ret
}


## TODO: 判断 多个服务是否已经激活
#   In :
#	$1 => isActive / noActive
#	$2 => yes / no. 是否需要静默输出
#	$3 => Service Name
#   Out:
#	$TPASS => 如果$1为isActive，指定服务已启动。若$1为noActive，指定服务未启动
#	$TFAIL => 如果$1为isActive，指定服务未启动。若$1为noActive，指定服务已启动
#	$TCONF => 代码问题
SvcActiveArr_FTLIB(){
	if [ $# -ne 3  ];then
		echo "[ Error ]: Function SvcActiveArr_FTLIB"
		return $TCONF
	fi
	
	local flag="$1"
	local quiet="$2"
	local svcname=""
	local svcnamearr="$3"
	local ret="$TPASS"

	local tmpret="$TPASS"
	local activesvc=""
	local noactivesvc=""

	# 遍历所有服务
	for svcname in ${svcnamearr[@]}
	do
		# 判断服务是否已经激活
		SvcActive_FTLIB "$flag" "$quiet" "$svcname"
		tmpret=$?

		if [ "$flag" == "isActive" -a $tmpret -eq $TPASS ];then
		# 服务当前已经激活
			activesvc="$activesvc $svcname"
		elif [ "$flag" == "isActive" -a $tmpret -eq $TFAIL ];then
		# 服务当前未激活
			noactivesvc="$noactivesvc $svcname"
			ret=$TFAIL
		elif [ "$flag" == "noActive" -a $tmpret -eq $TPASS ];then
		# 服务当前未激活
			noactivesvc="$noactivesvc $svcname"
		elif [ "$flag" == "noActive" -a $tmpret -eq $TFAIL ];then
		# 服务当前已经激活
			activesvc="$activesvc $svcname"
			ret=$TFAIL
		else
		# 异常
			echo "[ Error ]: SvcActiveArr_FTLIB function Results Abnormal (flag=$flag , ret=$tmpret)"
			return $TCONF
		fi
	done

	# 判断是否静默输出	
	if [ Z"$quiet" == Z"no" ];then
		echo "以下服务已激活: ($activesvc )"
		echo "以下服务未激活: ($noactivesvc )"
	fi

	return $ret
}


## TODO: 判断服务是否自启动
#   In :
#	$1 => isEnable / noEnable
#	$2 => yes / no. 是否需要静默输出
#	$3 => Service Name
#   Out:
#	$TPASS => 如果$1为isEnable，指定服务自启动。若$1为noEnable，指定服务未自启动
#	$TFAIL => 如果$1为isEnable，指定服务未自启动。若$1为noEnable，指定服务自启动
#	$TCONF => 代码问题
SvcEnable_FTLIB(){
	if [ $# -ne 3  ];then
		echo "[ Error ]: Function SvcEnable_FTLIB"
		return $TCONF
	fi
	
	local flag="$1"
	local quiet="$2"
	local svcname="$3"
	local ret=0

        # 判断是否存在systemctl
        which systemctl &>/dev/null
        if [ $? -eq 0 ];then
		# 判断服务是否自启动,如果自启动则返回0.(若服务不存在算作未自启)
		if [ Z"$quiet" == Z"yes" ];then
			systemctl is-enabled $svcname >/dev/null 
			ret=$?
		else
			echo -n "systemctl is-enabled $svcname : "
			systemctl is-enabled $svcname
			ret=$?
		fi
        else
                # 查看当前Init
                local initnum=$(runlevel | awk '{print $2}')

                if [ Z"$quiet" == Z"yes" ];then
                        chkconfig | grep $svcname | grep -q "${initnum}:启用"
                        ret=$?
                else
                        chkconfig | grep $svcname | grep -q "${initnum}:启用"
                        ret=$?
	
			# 打印日志，判断日志是否为空
			local tmplog=$(chkconfig | grep ${svcname} | awk  '{$1="";print $0}')
			# 判断是否为空
			if [ "Z${tmplog}" == "Z" ];then
				echo "chkconfig | grep ${svcname} :不存在 ${svcname} 服务"
			else
				echo "chkconfig | grep ${svcname} :$tmplog"
			fi
                fi

        fi


	# 如指定noEnable则结果反转
	if [ Z"$flag" == Z"noEnable"  ];then
		if [ $ret -eq 0 ];then
		# 服务自启动
			return $TFAIL
		else
		# 服务未自启动
			return $TPASS
		fi
	else
		if [ $ret -eq 0 ];then
		# 服务自启动
			return $TPASS
		else
		# 服务未自启动
			return $TFAIL
		fi
	fi	

	return $ret
}


## TODO: 判断 多个服务是否自启动
#   In :
#	$1 => isEnable / noEnable
#	$2 => yes / no. 是否需要静默输出
#	$3 => Service Name Arr
#   Out:
#	$TPASS => 如果$1为isEnable，指定服务自启动。若$1为noEnable，指定服务未自启动
#	$TFAIL => 如果$1为isEnable，指定服务未自启动。若$1为noEnable，指定服务自启动
#	$TCONF => 代码问题
SvcEnableArr_FTLIB(){
	if [ $# -ne 3  ];then
		echo "[ Error ]: Function SvcEnableArr_FTLIB"
		return $TCONF
	fi
	
	local flag="$1"
	local quiet="$2"
	local svcname=""
	local svcnamearr="$3"
	local ret="$TPASS"

	local tmpret="$TPASS"
	local enablesvc=""
	local noenablesvc=""

	# 遍历所有服务
	for svcname in ${svcnamearr[@]}
	do
		SvcEnable_FTLIB "$flag" "$quiet" "$svcname"
		tmpret=$?

		if [ "$flag" == "isEnable" -a $tmpret -eq $TPASS ];then
		# 服务默认自启动
			enablesvc="$enablesvc $svcname"
		elif [ "$flag" == "isEnable" -a $tmpret -eq $TFAIL ];then
		# 服务默认未自启动
			noenablesvc="$noenablesvc $svcname"
			ret=$TFAIL
		elif [ "$flag" == "noEnable" -a $tmpret -eq $TPASS ];then
		# 服务默认未自启动
			noenablesvc="$noenablesvc $svcname"
		elif [ "$flag" == "noEnable" -a $tmpret -eq $TFAIL ];then
		# 服务默认自启动
			enablesvc="$enablesvc $svcname"
			ret=$TFAIL
		else
		# 异常
			echo "[ Error ]: SvcEnableArr_FTLIB function Results Abnormal (flag=$flag , ret=$tmpret)"
			return $TCONF
		fi
	done

	# 判断是否静默输出	
	if [ Z"$quiet" == Z"no" ];then
		echo "开机自启动服务: ($enablesvc )"
		echo "开机未自启动服务: ($noenablesvc )"
	fi

	return $ret
}



## TODO: 判断 版本号是否符合需求相等
#   In :
#        $1 => 测试命令
#        $2 => 测试命令查看版本号的参数
#        $3 => 版本号
VersionEQTest_FTLIB(){
	if [ $# -ne 3 ];then
		echo "[ Error ]: Function VersionEQTest_FTLIB"
		return $TCONF
	fi

	local cmd="$1"
	local parameter="$2"
	local version="$3"

        # 测试版本
        which $cmd &> /dev/null
        if [ $? -eq 0 ];then
		echo -n "当前 $cmd 版本: "
                eval $cmd $parameter 
                eval $cmd $parameter 2>&1 | grep -q "$version"
                RetParse_FTLIB "要求 $cmd 版本为 $version" "False"
        else
                echo "不存在 ${cmd} 命令"
		OutputRet_FTLIB "$TFAIL"
                RetParse_FTLIB "存在 $cmd 命令" "False"
        fi
}


#######################################################


# 外部变量
export TPASS
export TFAIL
export TCONF

# 外部函数
export -f Clean_FTLIB
export -f OnCtrlC_FTLIB

export -f Init_FTLIB
export -f USAGE_FTLIB
export -f Exit_FTLIB

export -f PkgExist_FTLIB
export -f PkgExistArr_FTLIB
export -f SvcExist_FTLIB
export -f SvcExistArr_FTLIB
export -f SvcActive_FTLIB
export -f SvcActiveArr_FTLIB
export -f SvcEnable_FTLIB
export -f SvcEnableArr_FTLIB
export -f VersionEQTest_FTLIB

export -f OutputRet_FTLIB
export -f RetParse_FTLIB
